(function($, window, document, undefined){

	var

	pluginName = "parallax",

	/* ------------------------------------------------------- */
	/* DEFAULT OPTIONS
	/* ------------------------------------------------------- */

	defaults = {
		align: "center",
		cover: true,
		offsetx: 0,
		offsety: 0,
		start: "100%", /* number of pixels from window top. when the top edge of the element passes this point, the parallax effect will start */
		stop: 0, /* number of pixels from window top. when the bottom edge of the element passes this point, the parallax effect will stop */
		span: 250, /* the total distance travelled by the image during the parallax effect */
	};

	$.extend($.fn, {

		parallax: function(options){
			
			/* ------------------------------------------------------- */
			/* PLUGIN
			/* ------------------------------------------------------- */

			var command = typeof options === "string",
			options	= command ? options : $.extend(true, {}, defaults, options),
			args 	= arguments;

			function parallax(target, options){
				this.target = target;
				this.options = $.extend(true, {}, options);
				this.options = this.dapi(this.target, this.options);
				this.update();

				$(window).on("scroll", {t: this}, this.reqUpdate).on("resize", {t: this}, this.reqUpdate);
			}

			parallax.prototype.dapi = function(target, options){
				for(var o in options){
					if(target.data((pluginName + "-" + o).toLowerCase()) !== undefined){
						options[o] = target.data((pluginName + "-" + o).toLowerCase());
					}
				}

				return options;
			}

			parallax.prototype.reqUpdate = function(e){
				e.data.t.update();
			}

			parallax.prototype.update = function(){
				clearTimeout(this.timeout);
				this.timeout = setTimeout((function(t){
					return function(){
						var target 		= t.target,
							o 			= t.options,
							layers 		= target.children(),
							top 		= target.offset().top,
							h 			= target.height(),
							wh 			= $(window).height(),
							st			= $(window).scrollTop(),
							ost 		= typeof o.start === "string" && o.start.slice(o.start.length - 1) == "%" ? parseInt(o.start)*wh/100 : o.start;
							oen 		= typeof o.stop === "string" && o.stop.slice(o.stop.length - 1) == "%" ? parseInt(o.stop)*wh/100 : o.stop;
							p 			= top - st,
							a			= p - ost,
							b			= p - oen + h,
							v 			= Math.min(0, Math.max(-1, a/(b - a)));

						layers.each(function(){
							var css = {},
								d = v*($(this).height() - h);

							if(Modernizr && Modernizr.csstransforms3d){
								css[helpers.prefix.css + "transform"] = "translate3d(0," + d + "px,0)";
							}else{
								css["top"] = d + "px";
							}

							$(this).css(css);
						});
					}
				}(this)), 10);
			}
/*
			parallax.prototype.update = function(){
				var t = this;

				clearTimeout(this.timeout);
				this.timeout = setTimeout(function(){
					var top = t.target.offset().top,
						st = $(window).scrollTop(),
						wh = $(window).height(),
						h = t.target.height(),
						v = Math.max(-1, Math.min(0, (top - (st + wh))/(wh + h))),
						img = t.target.find("img"),
						speed = t.options.speed === false ? img.height() - h : t.options.speed;
						css = {};

					if(Modernizr && Modernizr.csstransforms3d){
						css[helpers.prefix.css + "transform"] = "translate3d(0," + (v*speed + Number(t.options.offset)) + "px,0)";
					}else{
						css["top"] = (v*speed + Number(t.options.offset)) + "px";
					}

					if(["right", "center", "left"].indexOf(t.options.xpos) != -1){
						css["position"] = "absolute";
						css["max-width"] = "none";

						if(t.options.xpos == "right" || t.options.xpos == "left"){
							css[t.options.xpos] = 0;
						}else{
							css["left"] = "50%";
							css["margin-left"] = -img.width/2;

							if(img.data("naturalwidth")){
								css["margin-left"] = -img.data("naturalwidth")/2;
							}else{
								var _img = new Image();
								$(_img).load(function(){
									img.data("naturalwidth", this.width);
									t.update();
								});
								_img.src = img.attr("src");
							}
						}
					}else
					if(!isNaN(t.options.xpos)){
						css["left"] = t.options.xpos;
					}

					img.css(css);
				}, 10);
			}
*/

			if(command){
				/* execute command */
				switch(options){
					case "ACTION":
						// DO ACTION
						return;
				}
			}else{
				/* initialize plugin */
				return $(this).each(function(){
					var instance = new parallax($(this), options);
					$(this).get(0)["_" + pluginName + "Instance"] = instance;
				});
			}
		}

	});

}(jQuery, window, document));